var
  fpc_system_lock: longint; export name 'fpc_system_lock';

procedure LockSystem; assembler; nostackframe;
asm
  ldr r0, .Lfpc_system_lock
  mov r1, #1
.Lloop:
  ldrex r2, [r0]
  cmp r2, #0
  itt eq
  strexeq r2, r1, [r0]
  cmpeq r2, #0
  bne .Lloop
  
  mov pc, lr
  
.Lfpc_system_lock:
  .long fpc_system_lock
end;

procedure UnlockSystem; assembler; nostackframe;
asm
  ldr r0, .Lfpc_system_lock
  mov r1, #1
  
  str r2, [r0]
  mov pc, lr
  
.Lfpc_system_lock:
  .long fpc_system_lock
end;

function InterLockedDecrement (var Target: longint) : longint; assembler; nostackframe;
asm
// lock
  ldr r3, .Lfpc_system_lock
  mov r1, #1
.Lloop:
  ldrex r2, [r3]
  cmp r2, #0
  itt eq
  strexeq r2, r1, [r3]
  cmpeq r2, #0
  bne .Lloop
// do the job
  ldr r1, [r0]
  sub r1, r1, #1
  str r1, [r0]
  mov r0, r1
// unlock and return
  str r2, [r3]
  mov pc, lr
  
.Lfpc_system_lock:
  .long fpc_system_lock
end;


function InterLockedIncrement (var Target: longint) : longint; assembler; nostackframe;
asm
// lock
  ldr r3, .Lfpc_system_lock
  mov r1, #1
.Lloop:
  ldrex r2, [r3]
  cmp r2, #0
  itt eq
  strexeq r2, r1, [r3]
  cmpeq r2, #0
  bne .Lloop
// do the job
  ldr r1, [r0]
  add r1, r1, #1
  str r1, [r0]
  mov r0, r1
// unlock and return
  str r2, [r3]
  mov pc, lr

.Lfpc_system_lock:
  .long fpc_system_lock
end;


function InterLockedExchange (var Target: longint;Source : longint) : longint; assembler; nostackframe;
asm

// lock
  ldr r3, .Lfpc_system_lock
  mov r2, #1
.Lloop:
  ldrex r2, [r3]
  cmp r2, #0
  itt eq
  strexeq r2, r12, [r3]
  cmpeq r2, #0
  bne .Lloop
// do the job
  ldr r2, [r0]
  str r1, [r0]
  mov r0, r2
// unlock and return
  mov r2, #0
  str r2, [r3]
  mov pc, lr

.Lfpc_system_lock:
  .long fpc_system_lock
end;

function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint; assembler; nostackframe;
asm
// lock
  ldr r3, .Lfpc_system_lock
  mov r2, #1
.Lloop:
  ldrex r2, [r3]
  cmp r2, #0
  itt eq
  strexeq r2, r12, [r3]
  cmpeq r2, #0
  bne .Lloop
// do the job
  ldr r2, [r0]
  add r1, r1, r2
  str r1, [r0]
  mov r0, r2
// unlock and return
  mov r2, #0
  str r2, [r3]
  mov pc, lr

.Lfpc_system_lock:
  .long fpc_system_lock
end;


function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;{ assembler; nostackframe;
asm
// lock
  ldr r12, .Lfpc_system_lock
  mov r3, #1
.Lloop:
  ldrex r4, [r12]
  cmp r4, #0
  itt eq
  strexeq r2, r1, [r12]
  cmpeq r2, #0
  bne .Lloop
// do the job
  ldr r3, [r0]
  cmp r3, r2
  it eq
  streq r1, [r0]
  mov r0, r3
// unlock and return
  mov r3, #0
  str r3, [r12]
  mov pc, lr

.Lfpc_system_lock:
  .long fpc_system_lock
end ['r1','r2','r3','r4'];}
begin
   LockSystem;
   result := target;
   if target=comperand then
      target := newvalue;
   UnlockSystem;
end;